package com.googlecode.alfrescocachingserver.extractor;

import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.extensions.webscripts.Description;

import com.googlecode.alfrescocachingserver.exceptions.ServiceException;
import com.googlecode.alfrescocachingserver.model.WebScriptCacheKey;
import com.googlecode.alfrescocachingserver.model.WebScriptResponse;

public class RegExResponseIdExtractor implements CacheIdExtractor
{
    private static final Logger LOG = LoggerFactory.getLogger(RegExResponseIdExtractor.class);

    private Pattern pattern;
    private int groupId;
    
    public RegExResponseIdExtractor()
    {
    }

    private RegExResponseIdExtractor(String uriTemplateStr, Description description, String[] parameters)
    {
        if (parameters == null || parameters.length == 0)
        {
            throw new ServiceException("RegExResponseIdExtractor requires a regular expression pattern to be passed in as the 1st parameter");
        }
        
        String regEx = parameters[0]; 
        
        if (!regEx.contains("(") && !regEx.contains(")"))
        {
            throw new ServiceException("RegExResponseIdExtractor regular expression must contain a group");
        }
        
        if (parameters.length > 1)
        {
            if (!NumberUtils.isNumber(parameters[1]) && NumberUtils.toInt(parameters[1]) <= 0)
            {
                throw new ServiceException("RegExResponseIdExtractor Group ID (2nd parameter) must be a valid number greater than 0");
            }
            
            groupId = NumberUtils.toInt(parameters[1]);
        }
        else
        {
            groupId = 1;
        }
        
        pattern = Pattern.compile(regEx);
    }

    @Override
    public Set<String> retrieveIds(WebScriptCacheKey webScriptCacheKey, final WebScriptResponse webScriptResponse)
    {
        Set<String> ids = new HashSet<String>();

        byte[] responseBytes = webScriptResponse.getResponseBytes();
        
        if (responseBytes != null && responseBytes.length > 0)
        {
        
            String response = new String(responseBytes);
            
            Matcher matcher = pattern.matcher(response);
            
            while (matcher.find())
            {
                String id = matcher.group(groupId);
                
                ids.add(id);
            }
        }
        
        LOG.debug("ids = {}", ids);
        
        return ids;
    }

    @Override
    public CacheIdExtractor createInstance(String uriTemplateStr, Description description, String[] parameters)
    {
        RegExResponseIdExtractor regExResponseIdExtractor = new RegExResponseIdExtractor(uriTemplateStr, description, parameters);
        
        return regExResponseIdExtractor;
    }
}
